//@version=6
indicator("AntiVestor - Top 'n Tail Zones", overlay=true)

// ============================================================
// SCALE PRESET
// ============================================================
gP = "Scale"
preset = input.string("ADD / Breadth", title="Scale Preset", options=["ADD / Breadth", "Percentage (0-100)", "Custom"], group=gP)

// ============================================================
// CUSTOM LEVELS (used only when Preset = Custom)
// ============================================================
gC = "Custom Levels"
c_bull_high = input.float( 2000.0, title="Bullish Extreme Upper", step=10, group=gC)
c_bull_low  = input.float( 1500.0, title="Bullish Extreme Lower", step=10, group=gC)
c_bear_high = input.float(-1500.0, title="Bearish Extreme Upper", step=10, group=gC)
c_bear_low  = input.float(-2000.0, title="Bearish Extreme Lower", step=10, group=gC)
c_chop_top  = input.float( 1000.0, title="Chop Zone Upper",       step=10, group=gC)
c_chop_bot  = input.float(-1000.0, title="Chop Zone Lower",       step=10, group=gC)

isCustom = preset == "Custom"
isPct    = preset == "Percentage (0-100)"

bull_high = isCustom ? c_bull_high : isPct ? 100.0 :  2000.0
bull_low  = isCustom ? c_bull_low  : isPct ?  90.0 :  1500.0
bear_high = isCustom ? c_bear_high : isPct ?  10.0 : -1500.0
bear_low  = isCustom ? c_bear_low  : isPct ?   0.0 : -2000.0
chop_top  = isCustom ? c_chop_top  : isPct ?  50.0 :  1000.0
chop_bot  = isCustom ? c_chop_bot  : isPct ?  50.0 : -1000.0

// Collapsed chop zone (upper == lower) is treated as a single midpoint level
midOnly = chop_top == chop_bot

// ============================================================
// DISPLAY
// ============================================================
gV = "Display"
right_offset = input.int(20, title="Forward Extension (bars)", minval=0, maxval=500, group=gV)
show_zero    = input.bool(true, title="Show Zero Line", group=gV)

// ============================================================
// COLOURS
// ============================================================
gK = "Colours"
bull_colour       = input.color(color.red,    title="Bullish Zone Colour",   group=gK)
bear_colour       = input.color(color.green,  title="Bearish Zone Colour",   group=gK)
chop_colour       = input.color(color.purple, title="Chop Zone Colour",      group=gK)
line_colour       = input.color(color.orange, title="Reference Line Colour", group=gK)
zero_line_colour  = input.color(color.black,  title="Zero Line Colour",      group=gK)
label_text_colour = input.color(color.white,  title="Label Text Colour",     group=gK)

// ============================================================
// EXTENSION
// ============================================================
right = bar_index + right_offset
var int left = bar_index

// Dummy plot to satisfy PineScript rendering requirement
plot(na, title="Invisible Plot")

// ============================================================
// ZONE BOXES
// ============================================================
var box bull_zone = na
var box bear_zone = na
var box chop_zone = na

chop_border = midOnly ? color(na) : chop_colour
chop_fill   = midOnly ? color(na) : color.new(chop_colour, 85)

if na(bull_zone)
    bull_zone := box.new(left=left, top=bull_high, right=right, bottom=bull_low, border_color=bull_colour, bgcolor=color.new(bull_colour, 85))
    bear_zone := box.new(left=left, top=bear_high, right=right, bottom=bear_low, border_color=bear_colour, bgcolor=color.new(bear_colour, 85))
    chop_zone := box.new(left=left, top=chop_top,  right=right, bottom=chop_bot, border_color=chop_border, bgcolor=chop_fill)
else
    box.set_right(bull_zone, right)
    box.set_top(bull_zone, bull_high)
    box.set_bottom(bull_zone, bull_low)
    box.set_border_color(bull_zone, bull_colour)
    box.set_bgcolor(bull_zone, color.new(bull_colour, 85))

    box.set_right(bear_zone, right)
    box.set_top(bear_zone, bear_high)
    box.set_bottom(bear_zone, bear_low)
    box.set_border_color(bear_zone, bear_colour)
    box.set_bgcolor(bear_zone, color.new(bear_colour, 85))

    box.set_right(chop_zone, right)
    box.set_top(chop_zone, chop_top)
    box.set_bottom(chop_zone, chop_bot)
    box.set_border_color(chop_zone, chop_border)
    box.set_bgcolor(chop_zone, chop_fill)

// ============================================================
// REFERENCE LINES
// Line objects rather than hline(), because preset-derived levels
// are not const/input qualified and hline() will not accept them.
// Anchored to the current bar, not the first bar: Pine rejects x
// coordinates more than ~10000 bars from bar_index (RE10026).
// extend.both means the anchor position is irrelevant visually.
// ============================================================
var line ln_chop_top = na
var line ln_chop_bot = na
var line ln_zero     = na

if na(ln_chop_top)
    ln_chop_top := line.new(x1=bar_index, y1=chop_top, x2=bar_index + 1, y2=chop_top, extend=extend.both, color=line_colour, style=line.style_dashed, width=1)
    ln_chop_bot := line.new(x1=bar_index, y1=chop_bot, x2=bar_index + 1, y2=chop_bot, extend=extend.both, color=line_colour, style=line.style_dashed, width=1)
    ln_zero     := line.new(x1=bar_index, y1=0.0,      x2=bar_index + 1, y2=0.0,      extend=extend.both, color=zero_line_colour, style=line.style_solid, width=1)
else
    line.set_xy1(ln_chop_top, bar_index, chop_top)
    line.set_xy2(ln_chop_top, bar_index + 1, chop_top)
    line.set_color(ln_chop_top, line_colour)

    line.set_xy1(ln_chop_bot, bar_index, chop_bot)
    line.set_xy2(ln_chop_bot, bar_index + 1, chop_bot)
    line.set_color(ln_chop_bot, midOnly ? color(na) : line_colour)

    line.set_xy1(ln_zero, bar_index, 0.0)
    line.set_xy2(ln_zero, bar_index + 1, 0.0)
    line.set_color(ln_zero, show_zero ? zero_line_colour : color(na))

// ============================================================
// LABELS (floating on the right)
// ============================================================
var label lbl_bull = label.new(x=na, y=na, text="", style=label.style_label_right)
var label lbl_bear = label.new(x=na, y=na, text="", style=label.style_label_right)
var label lbl_high = label.new(x=na, y=na, text="", style=label.style_label_right)
var label lbl_low  = label.new(x=na, y=na, text="", style=label.style_label_right)

label.set_xy(lbl_bull, right - 1, (bull_high + bull_low) / 2)
label.set_text(lbl_bull, "Bullish Extreme")
label.set_color(lbl_bull, bull_colour)
label.set_textcolor(lbl_bull, label_text_colour)

label.set_xy(lbl_bear, right - 1, (bear_high + bear_low) / 2)
label.set_text(lbl_bear, "Bearish Extreme")
label.set_color(lbl_bear, bear_colour)
label.set_textcolor(lbl_bear, label_text_colour)

label.set_xy(lbl_high, right - 1, chop_top)
label.set_text(lbl_high, midOnly ? "Midpoint" : "Relative High")
label.set_color(lbl_high, line_colour)
label.set_textcolor(lbl_high, label_text_colour)

// Lower reference label is parked off-chart when the chop zone collapses
if midOnly
    label.set_xy(lbl_low, na, na)
    label.set_text(lbl_low, "")
else
    label.set_xy(lbl_low, right - 1, chop_bot)
    label.set_text(lbl_low, "Relative Low")
    label.set_color(lbl_low, line_colour)
    label.set_textcolor(lbl_low, label_text_colour)